#include <iostream>
#include <random>
#include <sstream>
#include <iomanip>
#include <atomic>

/*
    uuid:32位16进制数字字符组成
    格式为8-4-4-4-12的32个字符
    如:550e8400-e29b-41d4-a716-446655440000

    我们通过生成8个 0-255之间的数字 加上一个8字节的序号 ，来组成uuid
    1.可以通过标准库中random_device来生成机器随机数，但是效率太低
    2.标准库还有一种生成随机数的类 mt19937 来生成伪随机数，同时使用random_device生成的机器随机数作为随机数种子
    3.但是mt19937生成的数范围很大,我们可以使用标准库中uniform_int_distribution来指定范围,同时用mt19937生成的随机数作为随机数种子
    4.我们使用stringstream来进行字符操作
*/

std::string uuid()
{
    std::random_device rd;
    std::mt19937 generator(rd());
    std::uniform_int_distribution<int> distribution(0, 255);

    std::stringstream ss;
    //将8个（0-255）数字变成16进制数字字符
    for (int i = 0; i < 8; i++)
    {
        ss << std::setw(2) << std::setfill('0') << std::hex << distribution(generator);
        if (i == 3 || i == 5 || i == 7)
        {
            ss << '-';
        }
    }

    //8字节数字序号
    static std::atomic<size_t> number(1);
    size_t num = number.fetch_add(1);

    for (int i = 7; i >= 0; i--)
    {
        //((num >> ((i * 8))) & 0xFF)每次取8位bit
        ss << std::setw(2) << std::setfill('0') << std::hex << ((num >> ((i * 8))) & 0xFF);
        if (i == 6)
        {
            ss << '-';
        }
    }

    return ss.str();
}

int main()
{
    for (int i = 0; i < 20; i++)
    {
        std::cout << uuid() << std::endl;
    }
    return 0;
}